//
// Project werewolf: http_filter.cpp
// Created by alfielin on 2021/11/17.
//

#pragma once

#include "hv/HttpService.h"
#include <memory>
#include <functional>

namespace nz {

class HttpFilterChain;

using FilterCallback = std::function<int(HttpRequest *, HttpResponse *, HttpFilterChain *)>;
using FilterSequence = std::vector<std::pair<FilterCallback, bool>>;

class HttpFilterChain {
private:
    int pos = 0;
    FilterSequence *sequence = nullptr;

public:

    HttpFilterChain() {
        this->pos = 0;
        sequence = nullptr;
    }

    explicit HttpFilterChain(FilterSequence *seq) {
        this->pos = 0;
        this->sequence = seq;
    }

    static std::shared_ptr<FilterSequence>
    build_sequence(std::initializer_list<std::pair<FilterCallback, bool>> initializer_list) {
        auto ret = std::make_shared<FilterSequence>();
        for (const auto &pp: initializer_list) {
            ret->push_back(pp);
        }
        return ret;
    }

    int filter_next(HttpRequest *req, HttpResponse *resp) {
        int ret = HTTP_STATUS_UNFINISHED;
        if ((sequence != nullptr) && (this->pos < sequence->size())) {
            auto pp = sequence->at(this->pos);
            this->pos += 1;
            if (pp.second) { // enabled
                ret = pp.first(req, resp, this);
            } else {
                ret = filter_next(req, resp);
            }
        }
        return ret;
    }

};

}
